/*
 * C Implementation: grib_set_bitmap
 *
 * Description: how to set a bitmap (位映射) in a GRIB message
 *
 */

#include <stdio.h>
#include <stdlib.h>

#include "eccodes.h"

int sfx_grib_set_bitmap()
{
    int err = 0;

    const char* infile  = "d:/sfxData/ECMWF/eccodes_test_data/regular_latlon_surface.grib1";
    const char* outfile = "d:/temp/out.set_bitmap_c.grib";

    FILE* in  = fopen(infile, "rb");
    FILE* out = fopen(outfile, "wb");

    codes_handle* h = codes_handle_new_from_file(0, in, PRODUCT_GRIB, &err);

    // 查看 BMP 是否存在
    long bitmapPresent = 0;
    CODES_CHECK(codes_get_long(h, "bitmapPresent", &bitmapPresent), 0);
    if (!bitmapPresent) {
        double m = -1;
        CODES_CHECK(codes_get_double(h, "missingValue", &m), 0);
    }

    // set missing value
    double missing = 9999;
    CODES_CHECK(codes_set_double(h, "missingValue", missing), 0);

    // get the size of the values array
    size_t values_len = 0;
    CODES_CHECK(codes_get_size(h, "values", &values_len), 0);
    // get data values
    double* values = (double*)malloc(values_len * sizeof(double));
    CODES_CHECK(codes_get_double_array(h, "values", values, &values_len), 0);

    // 设置位映射
    CODES_CHECK(codes_set_long(h, "bitmapPresent", 1), 0);
    for (int i = 0; i < 10; i++) {
        values[i] = missing;
    }

    CODES_CHECK(codes_set_double_array(h, "values", values, values_len), 0);

    // get the coded message in a buffer
    size_t size        = 0;
    const void* buffer = NULL;
    CODES_CHECK(codes_get_message(h, &buffer, &size), 0);

    // write the buffer in a file
    fwrite(buffer, 1, size, out);


    // free memory
    free(values);
    fclose(out);
    fclose(in);
    return 0;
}
